package com.hxexp.weixin.common.jsptag;

import java.io.File;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.http.HttpServletRequest;

import org.joda.time.LocalDate;
import org.springframework.util.StringUtils;

import com.hxexp.weixin.common.config.ConfigFileUtils;
import com.hxexp.weixin.common.security.SignatureHelper;
import com.hxexp.weixin.common.string.StringHelper;
import com.hxexp.weixin.common.web.HttpUtil;
import com.hxexp.weixin.constant.Gender;
import com.hxexp.weixin.constant.IdentificationType;
import com.hxexp.weixin.constant.OrderStatus;
import com.hxexp.weixin.constant.PassengerType;
import com.hxexp.weixin.constant.SchType;
import com.hxexp.weixin.constant.TicketState;
import com.hxexp.weixin.constant.WebAppVersion;

/**
 * 自定义函数标签类
 * @author li.jiang
 *
 */
public final class CustomFunctions {
    // 文件MD5值映射
    private static final ConcurrentMap<String, String> FILE_MD5_MAP = new ConcurrentHashMap<String, String>();

    private CustomFunctions() {
    }
    /**
     * 获取班次类型名称
     * @param schType 班次类型
     * @return 班次类型名称
     */
    public static String getSchTypeName(String schType) {
        return SchType.CODE_NAME_MAP.get(schType);
    }
    /**
     * 获取订单状态名称
     * @param orderStatus 订单状态
     * @return 订单状态名称
     */
    public static String getOrderStatusName(String orderStatus) {
        return OrderStatus.CODE_NAME_MAP.get(orderStatus);
    }
    /**
     * 获取车票状态名称
     * @param state 车票状态
     * @return 车票状态名
     */
    public static String getTicketStateName(String state) {
        String ticketStateName = "";
        if (!TicketState.INITIALIZE.equals(state)) {
            ticketStateName = TicketState.CODE_NAME_MAP.get(state);
        }
        return ticketStateName;
    }
    /**
     * 根据性别获取称谓
     * @param gender 性别
     * @return 称谓
     */
    public static String getGenderTitle(String gender) {
        if (Gender.MALE.equals(gender)) {
            return "先生";
        } else {
            return "女士";
        }
    }
    /**
     * 获取当前日期
     * @param dateFormat 日期格式字符串
     * @return 表示当前日期的字符串
     */
    public static String getCurrentDate(String dateFormat) {
        LocalDate now = LocalDate.now();
        return now.toString(dateFormat);
    }
    /**
     * 比较指定日期和当前日期
     * @param date 表示指定日期的字符串（格式：yyyy-M-d 或者 yyyy-MM-dd）
     * @return 比较结果（1:指定日期大于当前日期，0:指定日期等于当前日期，-1指定日期小于当前日期）
     */
    public static int compareWithCurrentDate(String date) {
        return LocalDate.parse(date).compareTo(LocalDate.now());
    }
    /**
     * 获取文件的MD5值
     * @param fileContextPath 文件上下文地址(例如：/css/main.css)
     * @return MD5
     */
    public static String getFileMD5(HttpServletRequest request, String fileContextPath) {
        String md5 = FILE_MD5_MAP.get(fileContextPath);
        if (md5 == null) {
            String realPath = HttpUtil.getFileRealPath(request, fileContextPath);
            md5 = SignatureHelper.encryptFileMD5(new File(realPath));
            FILE_MD5_MAP.put(fileContextPath, md5);
        }

        return md5;
    }

    /**
     * 获取页面title
     *
     * @param titleCode
     *            title编码
     * @return title名称
     */
    public static String getPageTitle(String version) {
        return WebAppVersion.TITLE_NAME_MAP.get(version);
    }

    /**
     * 获取证件类型名称
     *
     * @param IdentificationType
     *            证件类型
     * @return 证件类型名称
     */
    public static String getIdentificationTypeName(String identificationType) {
        return IdentificationType.CODE_NAME_MAP.get(identificationType);
    }

    /**
     * 获取隐藏的身份证信息
     *
     * @param IdentificationType
     *            证件类型
     * @param identificationNumber
     *            证件号码
     * @return 隐藏的证件号码
     */
    public static String getHiddenIdentificationNumber(String identificationNumber, String identificationType) {
        String _identificationNumber = identificationNumber; // NOSONAR
        if (identificationNumber != null && isIDCardNumber(identificationNumber, identificationType)) {
            _identificationNumber = StringHelper.hiddenIDNumber(identificationNumber);
        }

        return _identificationNumber;
    }

    /**
     * 获取乘客类型名称
     *
     * @param passengerType
     *            乘客类型
     * @return 乘客类型名称
     */
    public static String getPassengerTypeName(String passengerType) {
        return PassengerType.CODE_NAME_MAP.get(passengerType);
    }

    /**
     * 是否是身份证号码
     *
     * @param identificationNumber
     *            证件号码
     * @param identificationType
     *            证件号码
     * @return
     */
    public static boolean isIDCardNumber(String identificationNumber, String identificationType) {
        return identificationNumber.length() == 18 && IdentificationType.IDCARD.equals(identificationType);
    }

    /**
     * 是否为禁用出发城市缩写
     *
     * @param initial
     *            出发城市缩写
     * @return true:是禁用出发城市缩写；false:不是禁用出发城市缩写
     */
    public static boolean isDisableStartCityInitial(String initial) {
        if (StringUtils.isEmpty(initial)) {
            return true;
        }
        Properties p = ConfigFileUtils.getProperties("conf/context-setting.properties");
        String item = p.getProperty("disable_startcity_initial");
        String[] disableStartCityInitials = item.split(",");
        Arrays.sort(disableStartCityInitials, String.CASE_INSENSITIVE_ORDER);

        return Arrays.binarySearch(disableStartCityInitials, initial, String.CASE_INSENSITIVE_ORDER) > -1 ? true : false;
    }

    /**
     * 判断车站是否支持二维码检票
     *
     * @param stationId
     *            车站编号
     * @return
     */
    public static boolean isEnableQRCheckin(String stationId) {
        Properties p = ConfigFileUtils.getProperties("conf/context-setting.properties");
        String item = p.getProperty("qr_checkin_station");

        return Arrays.asList(item.split(",")).contains(stationId);
    }

    /**
     * 测试指定的文件是否存在
     *
     * @param request
     *            http请求
     * @param fileContextPath
     *            文件上下文地址(例如：/css/main.css)
     * @return true:文件存在；false:文件不存在
     */
    public static boolean isExistsFile(HttpServletRequest request, String fileContextPath) {
        String realPath = HttpUtil.getFileRealPath(request, fileContextPath);
        return new File(realPath).exists();
    }

    /**
     * 判断指定出发车站是否只支持车次查询
     *
     * @param stationId
     *            车站编号
     * @return
     */
    public static boolean isOnlySupportQuery(String stationId) {
        Properties p = ConfigFileUtils.getProperties("conf/context-setting.properties");
        String item = p.getProperty("only_support_query_station");

        return Arrays.asList(item.split(",")).contains(stationId);
    }

    /**
     * 是否为当代集团超长线禁用出发城市的缩写
     *
     * @param initial
     *            城市名称拼音缩写
     * @return true:是禁用出发城市缩写；false:不是禁用出发城市缩写
     */
    public static boolean isDisableUltraLongLineCityInitial(String initial) {
        Properties p = ConfigFileUtils.getProperties("conf/context-setting.properties");
        String item = p.getProperty("disable_startcity_ultra_long_initial");

        return Arrays.asList(item.split(",")).contains(initial);
    }

    /**
     * 判断车站是否支持指定的乘客类型
     *
     * @param startStationId
     *            出发站编码
     * @param passengerType
     *            乘客类型
     * @return true：支持，false:不支持
     */
    public static boolean isSupportPassengerType(String startStationId, String passengerType) {
        Properties p = ConfigFileUtils.getProperties("conf/context-setting.properties");
        if (PassengerType.ADULT.equals(passengerType)) {
            return true;
        } else if (PassengerType.CHILD.equals(passengerType)) {
            String item = p.getProperty("ticket_type_child");
            return Arrays.asList(item.split(",")).contains(startStationId);
        } else if (PassengerType.SPECIAL.equals(passengerType)) {
            String item = p.getProperty("ticket_type_disabled");
            return Arrays.asList(item.split(",")).contains(startStationId);
        } else {
            return false;
        }
    }

    /**
     * 判断车站是否支持指定的证件类型
     *
     * @param startStationId
     *            出发站编码
     * @param identificationType
     *            证件类型
     * @return true：支持，false:不支持
     */
    public static boolean isSupportCertificateType(String startStationId, String identificationType) {
        Properties p = ConfigFileUtils.getProperties("conf/context-setting.properties");
        if (IdentificationType.IDCARD.equals(identificationType)) {
            return true;
        } else if (IdentificationType.PASSPORT.equals(identificationType)) {
            String item = p.getProperty("certificate_type_passport");
            return Arrays.asList(item.split(",")).contains(startStationId);
        } else if (IdentificationType.OFFICERCARD.equals(identificationType)) {
            String item = p.getProperty("certificate_type_officers");
            return Arrays.asList(item.split(",")).contains(startStationId);
        } else {
            return false;
        }
    }

    /**
     * 是否禁用对应乘客信息条目
     *
     * @param startStationId
     *            出发站编码
     * @param passengerType
     *            乘客类型
     * @param identificationType
     *            证件类型
     * @return true: 禁用，false: 启用
     */
    public static boolean isDisablePassengerInfoItem(String startStationId, String passengerType, String identificationType) {
        if (PassengerType.CHILD.equals(passengerType)) {
            return !isSupportPassengerType(startStationId, passengerType);
        } else {
            return (!isSupportPassengerType(startStationId, passengerType)) || (!isSupportCertificateType(startStationId, identificationType));
        }
    }
}
